#include <iostream>
#include <vector>
#include <bitset>
using namespace std;

int main()
{
	int n, m;
	cin >> n >> m;
	vector<vector<int>> graph(n);

	// 构建无向图的邻接表
	for (int i = 0; i < m; i++) {
		int a, b;
		cin >> a >> b;
                a--;
                b--;
		graph[a].push_back(b);
		graph[b].push_back(a);
	}

	// 如果顶点数小于3，则无环
	if (n < 3) {
		cout << 0 << endl;
		return 0;
	}

	long long totalCycles = 0;

	// 枚举每个顶点作为环的最小顶点
	for (int u = 0; u < n; u++) {
		// dp[mask][x]: 从u出发，当前顶点集合为mask，且位于x的路径数
		vector<vector<long long>> dp(1 << n, vector<long long>(n, 0));
		dp[1 << u][u] = 1; // 初始状态

		// 遍历所有状态（位掩码）
		for (int mask = 1; mask < (1 << n); mask++) {
			for (int x = 0; x < n; x++) {
				if (dp[mask][x] == 0)
					continue; // 跳过无效状态

				// 遍历x的邻居
				for (int y : graph[x]) {
					// 忽略比起点u小的顶点
					if (y < u)
						continue;

					// 回到起点u且形成环（至少3个顶点）
					if (y == u) {
						if (bitset<32>(mask).count() >= 3) {
							totalCycles += dp[mask][x];
						}
					}
					// 扩展新顶点
					else if (!(mask & (1 << y))) {
						int new_mask = mask | (1 << y);
						dp[new_mask][y] += dp[mask][x];
					}
				}
			}
		}
	}

	// 每个环被计数两次（顺时针和逆时针），除以2得到最终结果
	totalCycles /= 2;
	cout << totalCycles << endl;

	return 0;
}